package preka.prefuse.action;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;

import prefuse.Visualization;
import prefuse.action.GroupAction;
import prefuse.data.expression.Predicate;
import prefuse.visual.VisualItem;
import prefuse.visual.expression.VisiblePredicate;
import preka.IVC;
import preka.prefuse.visual.VisualInstance;
import preka.prefuse.visual.VisualInstances;
import weka.clusterers.FarthestFirst;

/**
 * TODO escrever descrição
 * {@link #setFilterPredicate(Predicate)}
 *
 * @author <a href="http://vhbarros.org">Vitor Hugo Barros</a>
 */
public class IVCFarthestFirst extends Heuristic {

    /** A reference to filtering predicate for this Action */
    //protected VisualInstances m_visualInstances;

    /**
     * Create a new IVCFarthestFirst that processes all groups.
     * @see Visualization#ALL_ITEMS
     */
    public IVCFarthestFirst() {
        this(null, Visualization.ALL_ITEMS);
    }

    /**
     * Create a new IVCFarthestFirst that processes all groups.
     * @param vis the {@link prefuse.Visualization} to process
     * @see Visualization#ALL_ITEMS
     */
    /*public IVCFarthestFirst(Visualization vis) {
        this(vis, Visualization.ALL_ITEMS);
    }*/

    /**
     * Create a new IVCFarthestFirst that processes the specified group.
     * @param group the name of the group to process
     */
    public IVCFarthestFirst(IVC ivc) {
        this(ivc, Visualization.ALL_ITEMS);
    }

    /**
     * Create a new IVCFarthestFirst that processes the specified group.
     * @param group the name of the group to process
     * @param vinsts visual instances associated with the IVC process
     */
    /*public IVCFarthestFirst(String group, VisualInstances vinsts) {
        this(null, group, vinsts);
    }*/

    /**
     * Create a new IVCFarthestFirst that processes the specified group.
     * @param vis the {@link prefuse.Visualization} to process
     * @param group the name of the group to process
     */
    public IVCFarthestFirst(IVC ivc, String group) {
        //this(vis, group, null);
        super(ivc, group);
    }

    /**
     * Create a new IVCFarthestFirst that processes the specified group.
     * @param vis the {@link prefuse.Visualization} to process
     * @param group the name of the group to process
     * @param vinsts visual instances associated with the IVC process
     */
    /*public IVCFarthestFirst(Visualization vis, String group, VisualInstances vinsts) {
        super(vis, group);
        m_visualInstances = vinsts;
    }*/

    // ------------------------------------------------------------------------

    /**
     * @see prefuse.action.Action#run(double)
     */
    //public void run(double frac) {
    //    System.out.println("Hey! frac:"+frac);
    //}
    public void moveNode() {
        VisualInstance farthestNode;
        double [] pos;

        farthestNode = getFarthestNode();
        pos = getRandomClusterPosition(getHeuristicCluster(farthestNode.getClassName()));

        /*System.out.println("Instância: "+farthestNode.getNumInstance()+
                           " Cluster: "+getHeuristicCluster(farthestNode.getClassName())+
                           " X: "+pos[0]+" Y:"+pos[1]);*/

        moveInstance(farthestNode, pos[0], pos[1]);
    }

    private VisualInstance getFarthestNode() {
        VisualInstance currNode, farthestNode = null;
        VisualItem currItem;
        double maxdist = Double.MIN_VALUE;
        double centerx, centery;
        double currDist;
        String className;

        try {
            for (int i = 0; i < m_IVC.getNumClasses(); i++) {

                VisualItem vi = m_IVC.getVisualization().getVisualItem(IVC.NODES_GROUP, m_IVC.getNodeByInstanceAttr((i+1)*-1));
                centerx = vi.getX();
                centery = vi.getY();
                className = getHeuristicClassName((i+1)*-1);
                //System.out.println("Centro:"+i+"/"+(i+1)*-1+" ("+className+")"+" X:"+centerx+" Y:"+centery);

                ArrayList notMovedVisualInstances =  m_IVC.getVisualInstances().getNotMovedVisualInstances(m_IVC.getVisualization(),
                                                                                                           IVC.NODES_GROUP,
                                                                                                           null);

                Iterator instances = notMovedVisualInstances.iterator();
                while (instances.hasNext()){
                    currNode = (VisualInstance) instances.next();
                    if (currNode.getClassName().equals(className)) {
                        currItem = m_vis.getVisualItem(IVC.NODES_GROUP, m_IVC.getNodeByInstanceAttr(currNode.getNumInstance()));
                        currDist = m_IVC.distance(centerx, centery, currItem.getX(), currItem.getY());
                        if (maxdist < currDist) {
                            maxdist = currDist;
                            farthestNode = currNode;
                            //System.out.println("Instance:"+currNode.getNumInstance()+" Class:"+currNode.getClassName()+" Distance:"+maxdist);
                        }
                    }
                }

            }

        } catch (Exception ex) {
            Logger.getLogger(IVCFarthestFirst.class.getName()).log(Level.SEVERE, null, ex);
        }

        return farthestNode;
    }




} // end of class IVCFarthestFirst
